/*
 * app_hub_api.c
 *
 *  Created on: 2023年7月19日
 *      Author: HXF
 */

#include "app_hub_api.h"
#include "app_log.h"
#include "string.h"
#include "device.h"
#include "net_rolling_code.h"
#include "btl_reset_info.h"
#define WAIT_ACK_TIMEOUT_MS (32768UL) //1S
#define GET_RSSR_TIMER_MS (32768UL) //1S
#define DELAY_COM_TX_TASK_TIMER_MS (65536UL) //2S
typedef enum{
  USART_RX_STEP_IDLE,
  USART_RX_STEP_POP,
  USART_RX_STEP_MEDIATOR,
}USART_RX_EVT_STEP_E;

typedef enum{
  USART_TX_STEP_IDLE,
  USART_TX_STEP_POP,
  USART_TX_STEP_MEDIATOR,
  USART_TX_STEP_WAITACK,
  USART_TX_STEP_RTNS,
}USART_TX_EVT_STEP_E;

static USART_RX_EVT_STEP_E usart_rx_step = USART_RX_STEP_IDLE;
static USART_TX_EVT_STEP_E usart_tx_step = USART_TX_STEP_IDLE;

static hub_api_rx_evt_t usart_rx_evt = {0};
static hub_api_tx_evt_t usart_tx_evt = {0};
static hub_api_usart_msg_t usart_rx_pkt = {0};
static hub_api_usart_msg_t usart_tx_pkt = {0};
static hub_api_usart_msg_t usart_ack_pkt = {0};

static unsigned char waitack = 0;
static bool wait_timeout = false;

bool hub_log_enable = false;

void DS_hub_api_init(void)
{
#ifdef HUB_DEVICE
  unsigned char needinit = 1;
  unsigned char enable_retrans = 1;
  unsigned char reset_mode = 0xff;
  unsigned char delay_txtask = 1;

  usart_rx_step = USART_RX_STEP_IDLE;
  usart_tx_step = USART_TX_STEP_IDLE;
  DS_app_hub_api_event_link_init();

  get_api_log_enable(HUB_API_LOG, &hub_log_enable);
  set_reset_enable(0);
  setThisParam(ENbyResetMode, &reset_mode);
  setThisParam(ENbyCfgReq, (unsigned char *)&needinit);
  setThisParam(ENbyEnableRetrans, (unsigned char *)&enable_retrans); //使能重传

  if(reset_getResetReason() == BOOTLOADER_RESET_REASON_GO){
      DS_com_Txbuff("\r\nsuccess\r\n", strlen("\r\nsuccess\r\n"));
      start_delay_com_tx_task(DELAY_COM_TX_TASK_TIMER_MS, NULL);
      delay_txtask = 1;
  }else{
      delay_txtask = 0;
  }
  setThisParam(ENbyDelayTxTask, &delay_txtask);
  DS_hub_api_antenna_init();
  DS_hub_api_txpower_init();
  DS_hub_api_ctune_init();
  DS_hub_api_lfxo_ctune_init();
  DS_hub_api_creat_hub_event(NEED_INIT, &needinit, 1);
  start_avg_rssi_Timer(GET_RSSR_TIMER_MS, NULL);  //测试算avg_rssi的接口函数
  start_fix_10S_Timer(327680, NULL);
  //extern bool test_check_ota_history_cache_is_too_many(void);
  //test_check_ota_history_cache_is_too_many();
#endif
}

void DS_hub_api_usart_rx_event_task(void)
{
  switch(usart_rx_step){
    case USART_RX_STEP_IDLE:
      if(!DS_app_hub_api_usart_rx_event_link_is_empty()){
          usart_rx_step = USART_RX_STEP_POP;
      }else{
    #if(HUB_API_TEST)
          //DS_hub_api_usart_listen();
    #else
          //链表空，没有任务，可以休眠
    #endif
      }
      break;
    case USART_RX_STEP_POP:
      if(DS_hub_api_get_usart_rx_event(&usart_rx_evt) == 0){
          usart_rx_step = USART_RX_STEP_MEDIATOR;
      }else{
          if(hub_log_enable){
              DS_app_log_error("usart rx link pop error\r\n");
          }
          usart_rx_step = USART_RX_STEP_IDLE;
      }
      break;
    case USART_RX_STEP_MEDIATOR:
      if(usart_rx_evt.channel == EVT_USART_RX){
          usart_rx_pkt = usart_rx_evt.msg.usart_msg;
          if(DS_hub_api_usart_rx_event_mediator(&usart_rx_pkt, &usart_ack_pkt) == 0){

          }else{
              if(hub_log_enable){
                  DS_app_log_error("usart rx event mediator error\r\n");
              }
          }
      }
      usart_rx_step = USART_RX_STEP_IDLE;
      break;
    default:
      usart_rx_step = USART_RX_STEP_IDLE;
      break;
  }
}

void DS_hub_api_usart_tx_event_task(void)
{
  unsigned char delay_txtask = 0;
  getThisParam(ENbyDelayTxTask, &delay_txtask);
  if(delay_txtask){
      return;
  }
  switch(usart_tx_step){
    case USART_TX_STEP_IDLE:
      if(!DS_app_hub_api_usart_tx_event_link_is_empty()){
          usart_tx_step = USART_TX_STEP_POP;
      }else{
          //链表空，没有任务，可以休眠
      }
      break;
    case USART_TX_STEP_POP:
      if(DS_hub_api_get_usart_tx_event(&usart_tx_evt) == 0){
          usart_tx_step = USART_TX_STEP_MEDIATOR;
      }else{
          if(hub_log_enable){
              DS_app_log_error("usart tx link pop error\r\n");
          }
          usart_tx_step = USART_TX_STEP_IDLE;
      }
      break;
    case USART_TX_STEP_MEDIATOR:
      if(usart_tx_evt.channel == EVT_USART_TX){
          usart_tx_pkt = usart_tx_evt.msg.usart_msg;
          if(DS_hub_api_usart_tx_event_mediator(&usart_tx_pkt, &waitack) == 0){
              //判断是否需要超时应答判断的逻辑
              if(waitack == 0){
                  usart_tx_step = USART_TX_STEP_IDLE;
              }else{
                  start_wait_ack_Timer(WAIT_ACK_TIMEOUT_MS, &wait_timeout);
                  usart_tx_step = USART_TX_STEP_WAITACK;
              }
          }else{
              if(hub_log_enable){
                  DS_app_log_error("usart tx event mediator error\r\n");
              }
              usart_tx_step = USART_TX_STEP_IDLE;
          }
      }else{
          usart_tx_step = USART_TX_STEP_IDLE;
      }
      break;
    case USART_TX_STEP_WAITACK:
      //超时判断
      //如果超时，去重发
      //      USART_TX_STEP_RTNS
      //如果收到应答，check_usart_active_evt_is_finish(usart_tx_pkt.fcode) == true
      //      回到USART_TX_STEP_IDLE
      if(wait_timeout){
          usart_tx_step = USART_TX_STEP_RTNS;
      }else{
          if(check_usart_active_evt_is_finish(usart_tx_pkt.fcode)){
              stop_wait_ack_Timer(&wait_timeout);
              usart_tx_step = USART_TX_STEP_IDLE;
          }
      }
      break;
    case USART_TX_STEP_RTNS:
      DS_hub_api_creat_usart_retransmission(&usart_tx_pkt);
      usart_tx_step = USART_TX_STEP_IDLE;
      break;
    default:
      usart_tx_step = USART_TX_STEP_IDLE;
      break;
  }
}


void DS_hub_api_task(void)
{
#ifdef HUB_DEVICE
  DS_hub_api_usart_listen();
  //hub_api_test();
  DS_hub_api_usart_rx_event_task();
  DS_hub_api_usart_tx_event_task();
  if(bufferIsEmpty(&com_TXBuff)){
      hub_do_reset();
  }
  hub_delay_delete_rfm();
#endif
}

